/**
 * 
 */
package info.niwota.web.apache;

import info.niwota.web.Debug;
import info.niwota.web.SessionManager;

import java.io.IOException;
import java.io.OutputStream;

import jvs.peer.io.ChannelManager;
import jvs.peer.xmpp.XmppWebAdapter;

import org.json.JSONObject;

import x.org.apache.http.HttpEntity;
import x.org.apache.http.HttpRequest;
import x.org.apache.http.HttpResponse;
import x.org.apache.http.HttpStatus;
import x.org.apache.http.ProtocolVersion;
import x.org.apache.http.RequestLine;
import x.org.apache.http.StatusLine;
import x.org.apache.http.message.BasicHttpRequest;
import x.org.apache.http.message.BasicHttpResponse;
import x.org.apache.http.message.BasicRequestLine;
import x.org.apache.http.message.BasicStatusLine;
import x.org.apache.http.protocol.BasicHttpContext;
import x.org.apache.http.protocol.HttpContext;
import x.org.apache.http.protocol.SyncBasicHttpContext;
import android.content.Context;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class XmppAdapter extends HttpAdapter implements XmppWebAdapter {
	private static final HttpContext webContext = new SyncBasicHttpContext(null);

	private static final ProtocolVersion protocol = new ProtocolVersion("http",
			1, 1);

	private static final String TAG = "XmppAdapter";

	public XmppAdapter(Context ctx) {
		super(ctx);
	}

	private HttpContext createContext(String peer) {
		String jid = ChannelManager.getInstance().getJid();

		HttpContext c = new BasicHttpContext(null);
		c.setAttribute(SessionManager.WEB_CONTEXT_KEY, webContext);
		c.setAttribute(SessionManager.WEB_JID_KEY, jid);
		c.setAttribute(SessionManager.WEB_PID_KEY, peer);

		return c;
	}

	/**
	 * @throws IOException
	 * 
	 */
	public void handle(JSONObject args, OutputStream os) throws Exception {
		if (Debug.DEBUG) {
			Log.d(TAG, "handle: " + args);
		}
		final String peer = getString(args, "peer");
		final String uri = getString(args, "uri");
		final String q = getString(args, "q");
		final String uriq = uriq(uri, q);
		//
		RequestLine requestLine = new BasicRequestLine("GET", uriq, protocol);
		HttpRequest req = new BasicHttpRequest(requestLine);
		StatusLine statusLine = new BasicStatusLine(protocol, HttpStatus.SC_OK,
				null);
		HttpResponse resp = new BasicHttpResponse(statusLine);

		HttpContext context = createContext(peer);

		super.handle(req, resp, context);
		//
		HttpEntity entity = resp.getEntity();
		entity.writeTo(os);

		if (Debug.DEBUG) {
			Log.d(TAG, "handle exiting");
		}
	}
	
	private String getString(JSONObject args, String key) {
		try {
			return args.getString(key);
		} catch (Exception e) {
			//
		}
		return null;
	}

	public void upload(JSONObject args) throws Exception {
		if (Debug.DEBUG) {
			Log.d(TAG, "upload: " + args);
		}
		try {
			final String cid = getString(args, "cid");
			final String tag = getString(args, "tag");
			final String peer = getString(args, "peer");
			final String uri = getString(args, "uri");
			final String q = getString(args, "q");

			final String uriq = uriq(uri, q);

			String postback = getString(args, "postback");

			RequestLine requestLine = new BasicRequestLine("GET", uriq,
					protocol);
			HttpRequest req = new BasicHttpRequest(requestLine);

			StatusLine statusLine = new BasicStatusLine(protocol,
					HttpStatus.SC_OK, null);
			HttpResponse resp = new BasicHttpResponse(statusLine);

			HttpContext context = createContext(peer);

			super.handle(req, resp, context);
			//
			HttpEntity entity = resp.getEntity();

			if (Debug.DEBUG) {
				Log.d(TAG, "entity: " + entity);
			}

			// TODO check auth,always owner?
			String name = System.currentTimeMillis() + "";
			int access = 1;

			FileUploader.upload(postback, entity, peer, uri, name, access, cid,
					tag);

		} catch (Exception e) {
			e.printStackTrace();

			throw e;
		}
		if (Debug.DEBUG) {
			Log.d(TAG, "upload exiting");
		}
	}

	private String uriq(String uri, String q) {
		return uri + (uri.indexOf('?') == -1 ? "?" : "&") + (q == null ? "xmpp=true" : q + "&xmpp=true");
	}

	public String getNetwork() {
		return ChannelManager.NETWORK_XMPP;
	}
}
